package io.renren.modules.table.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.NumberUtil;

import io.renren.common.utils.R;
import io.renren.modules.com.dao.ComCollectionRecordDao;
import io.renren.modules.com.dao.ComContractDao;
import io.renren.modules.com.dao.ComCrChargingitemDao;
import io.renren.modules.com.entity.ComColModel;
import io.renren.modules.com.entity.ComCollectionRecordEntity;
import io.renren.modules.com.entity.ComContractEntity;
import io.renren.modules.com.entity.ComCrChargingitemEntity;
import io.renren.modules.com.entity.ComGroupHeaders;
import io.renren.modules.table.entity.AllocationSummaryEntity;
import io.renren.modules.table.service.AccountsReceivableSummaryReportService;

@Service("accountsReceivableSummaryReportService")
public class AccountsReceivableSummaryReportServiceImpl implements AccountsReceivableSummaryReportService {

	@Autowired
	private ComContractDao comContractDao;

	@Autowired
	private ComCrChargingitemDao comCrChargingitemDao;

	@Autowired
	private ComCollectionRecordDao comCollectionRecordDao;

	public R initialization() {
		return initializationPrivate();
	}

	private R initializationPrivate() {
		Map<String, Object> map = new HashMap<String, Object>();
		SimpleDateFormat one = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat two = new SimpleDateFormat("yyyy年MM月dd日");
		Date nowDate = new Date();
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(nowDate);
		calendar.set(Calendar.DATE, calendar.getActualMinimum(Calendar.DATE));
		calendar.set(Calendar.MONTH, calendar.getActualMinimum(Calendar.MONTH));
		Date dateMonthS = calendar.getTime();
		map.put("dateMonthS", one.format(dateMonthS));
		calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
		calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
		Date dateMonthE = calendar.getTime();
		map.put("dateMonthE", one.format(dateMonthE));
		List<String> itemList = itemList();
		// 初始化jqgrid标题名
		map.put("caption", "应收款明细报表(" + two.format(dateMonthS) + "至" + two.format(dateMonthE) + ")");
		// 初始化jqgrid表头列名
		map.put("colNames", initializationColNames(itemList));
		// 初始化jqgrid表头列名属性
		map.put("colModel", initializationColModel(itemList));
		// 初始化jqgrid分组表头
		map.put("groupHeaders", initializationGroupHeaders(itemList));
		return R.ok(map);
	}

	public R changeJqGrid(AllocationSummaryEntity allocationSummary) {
		return changeJqGridPrivate(allocationSummary);
	}

	private R changeJqGridPrivate(AllocationSummaryEntity allocationSummary) {
		Map<String, Object> map = new HashMap<String, Object>();
		SimpleDateFormat one = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat two = new SimpleDateFormat("yyyy年MM月dd日");
		Date sd = DateUtil.parse(allocationSummary.getDateMonthS(), one);
		Date ed = DateUtil.parse(allocationSummary.getDateMonthE(), one);
		List<String> itemList = null;
		if (null != allocationSummary.getItems() && StringUtils.isNotBlank(allocationSummary.getItems())
				&& !StringUtils.equals("点击选择...", allocationSummary.getItems().trim())) {
			itemList = new ArrayList<String>(Arrays.asList(allocationSummary.getItems().replace(" ", "").split(",")));
		} else {
			itemList = itemList();
		}
		// 初始化jqgrid标题名
		map.put("caption", "应收款明细报表(" + two.format(sd) + "至" + two.format(ed) + ")");
		// 初始化jqgrid表头列名
		map.put("colNames", initializationColNames(itemList));
		// 初始化jqgrid表头列名属性
		map.put("colModel", initializationColModel(itemList));
		// 初始化jqgrid分组表头
		map.put("groupHeaders", initializationGroupHeaders(itemList));
		return R.ok(map);
	}

	private List<String> itemList() {
		List<String> itemList = new ArrayList<String>();
		itemList.add("租金");
		itemList.add("物业费");
		itemList.add("管理费");
		itemList.add("公共能耗费");
		itemList.add("居间服务费");
		itemList.add("保证金");
		itemList.add("停车费");
		itemList.add("其他");
		itemList.add("租场费");
		itemList.add("合计");
		return itemList;
	}

	/**
	 * 初始化jqgrid表头列名
	 * 
	 * @param itemList
	 * @return
	 */
	private List<String> initializationColNames(List<String> itemList) {
		List<String> colNames = CollectionUtil.newArrayList("楼号", "房号", "合同号");
		for (int i = 0; i < 3; i++) {
			for (String item : itemList) {
				colNames.add(item);
			}
		}
		return colNames;
	}

	/**
	 * 初始化jqgrid表头列名属性
	 * 
	 * @param itemList
	 * @return
	 */
	private List<ComColModel> initializationColModel(List<String> itemList) {
		List<ComColModel> colModelList = new ArrayList<ComColModel>();
		// 楼号
		ComColModel comColModel = new ComColModel();
		comColModel.setName("buildIds");
		comColModel.setWidth(100);
		comColModel.setAlign("center");
		comColModel.setFrozen(true);
		colModelList.add(comColModel);
		// 房号
		comColModel = new ComColModel();
		comColModel.setName("assetIds");
		comColModel.setWidth(100);
		comColModel.setAlign("center");
		comColModel.setFrozen(true);
		colModelList.add(comColModel);
		// 合同号
		comColModel = new ComColModel();
		comColModel.setName("contractNo");
		comColModel.setWidth(100);
		comColModel.setAlign("center");
		comColModel.setFrozen(true);
		colModelList.add(comColModel);
		for (int i = 0; i < 3; i++) {
			for (String item : itemList) {
				comColModel = new ComColModel();
				comColModel.setName(i + item);
				comColModel.setWidth(100);
				comColModel.setAlign("right");
				colModelList.add(comColModel);
			}
		}
		return colModelList;
	}

	/**
	 * 初始化jqgrid分组表头
	 * 
	 * @param itemList
	 * @return
	 */
	private List<ComGroupHeaders> initializationGroupHeaders(List<String> itemList) {
		List<ComGroupHeaders> comGroupHeadersList = new ArrayList<ComGroupHeaders>();
		ComGroupHeaders comGroupHeaders = null;
		for (int i = 0; i < 3; i++) {
			comGroupHeaders = new ComGroupHeaders();
			comGroupHeaders.setStartColumnName(i + itemList.get(0));
			comGroupHeaders.setNumberOfColumns(itemList.size());
			switch (i) {
			case 0:
				comGroupHeaders.setTitleText("应收金额");
				break;
			case 1:
				comGroupHeaders.setTitleText("已收金额");
				break;
			case 2:
				comGroupHeaders.setTitleText("未收金额");
				break;
			}
			comGroupHeadersList.add(comGroupHeaders);
		}
		return comGroupHeadersList;
	}

	public List<Map<String, Object>> queryList(Map<String, Object> map) {
		return queryListPrivate(map);
	}

	private List<Map<String, Object>> queryListPrivate(Map<String, Object> map) {
		List<String> itemList = null;
		if (null != map.get("items") && StringUtils.isNotBlank(map.get("items").toString().trim())
				&& !StringUtils.equals("点击选择...", map.get("items").toString().trim())) {
			itemList = new ArrayList<String>(Arrays.asList(map.get("items").toString().replace(" ", "").split(",")));
		} else {
			itemList = itemList();
		}
		map.put("itemList", itemList);
		List<ComCollectionRecordEntity> comCollectionRecordList = comCollectionRecordDao.arsr(map);
		if (CollectionUtil.isEmpty(comCollectionRecordList)) {
			return null;
		}
		List<Long> crSerialNoList = null;
		String buildIds = null;
		String assetIds = null;
		String contractNo = null;
		Double a = null;
		Double b = null;
		Double c = null;
		Double at = 0.0;
		Double bt = 0.0;
		Double ct = 0.0;
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMaximumFractionDigits(2);
		nf.setRoundingMode(RoundingMode.UP);
		nf.setGroupingUsed(false);
		int flag = 0;
		Class<? extends ComContractEntity> comContractEntityClass = null;
		Map<String, String> contract = null;
		ComContractEntity comContractEntity = null;
		List<Map<String, Object>> chinaJoy = new ArrayList<Map<String, Object>>();
		List<ComCrChargingitemEntity> comCrChargingitemList = null;
		for (ComCollectionRecordEntity comCollectionRecordEntity : comCollectionRecordList) {
			comContractEntityClass = null;
			Map<String, Object> alphabetBear = alphabetBear(itemList);
			buildIds = comCollectionRecordEntity.getBuildIds();
			if (null == buildIds) {
				map.remove("a");
				alphabetBear.put("buildIds", "");
			} else {
				map.put("a", buildIds);
				alphabetBear.put("buildIds", buildIds);
			}
			assetIds = comCollectionRecordEntity.getAssetIds();
			if (null == assetIds) {
				map.remove("b");
				alphabetBear.put("assetIds", "");
			} else {
				map.put("b", assetIds);
				alphabetBear.put("assetIds", assetIds);
			}
			contractNo = comCollectionRecordEntity.getContractNo();
			if (null == contractNo) {
				map.remove("c");
				alphabetBear.put("contractNo", "");
			} else {
				map.put("c", contractNo);
				alphabetBear.put("contractNo", contractNo);
				comContractEntity = comContractDao.queryByContractNo(contractNo);
				if (null != comContractEntity) {
					comContractEntityClass = comContractEntity.getClass();
					if (StringUtils.equals("1", comContractEntity.getSuppleFlag())) {
						contract = contractOld();
					} else {
						contract = contractNew();
					}
				}
			}
			crSerialNoList = comCollectionRecordDao.macBook(map);
			map.put("crSerialNoList", crSerialNoList);
			comCrChargingitemList = comCrChargingitemDao.superMario(map);
			for (ComCrChargingitemEntity comCrChargingitemEntity : comCrChargingitemList) {
				a = null;
				b = null;
				if (null != comContractEntityClass) {
					try {
						a = (Double) comContractEntityClass
								.getMethod(contract.get(comCrChargingitemEntity.getChargingItem()))
								.invoke(comContractEntity);
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					} catch (IllegalArgumentException e) {
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						e.printStackTrace();
					} catch (NoSuchMethodException e) {
						e.printStackTrace();
					} catch (SecurityException e) {
						e.printStackTrace();
					}
				}
				if (null == a) {
					a = 0.0;
					flag++;
				} else {
					alphabetBear.put(0 + comCrChargingitemEntity.getChargingItem(), a);
				}
				at += a;
				if (null == comCrChargingitemEntity.getPayAmount()) {
					b = 0.0;
					flag++;
				} else {
					b = comCrChargingitemEntity.getPayAmount();
					alphabetBear.put(1 + comCrChargingitemEntity.getChargingItem(), b);
				}
				bt += b;
				c = NumberUtil.sub(a, b);
				if (flag != 2 || c != 0) {
					alphabetBear.put(2 + comCrChargingitemEntity.getChargingItem(), NumberUtil.sub(a, b));
				}
				ct += c;
				flag = 0;
			}
			if (at != 0) {
				alphabetBear.put("0合计", nf.format(at));
			}
			if (bt != 0) {
				alphabetBear.put("1合计", nf.format(bt));
			}
			if (ct != 0) {
				alphabetBear.put("2合计", nf.format(ct));
			}
			chinaJoy.add(alphabetBear);
		}
		return chinaJoy;
	}

	private Map<String, String> contractOld() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("租金", "getTotalPrice");
		map.put("物业费", "getTotalManage");
		map.put("管理费", "getTotalProperty");
		map.put("公共能耗费", "getTotalEnergy");
		map.put("居间服务费", "getTotalInter");
		map.put("保证金", "getTotalBond");
		map.put("停车费", "getTotalStop");
		map.put("其他", "getTotalOther");
		map.put("租场费", "getTotalOther1");
		return map;
	}

	private Map<String, String> contractNew() {
		Map<String, String> map = new HashMap<String, String>();
		map.put("租金", "getStotalPrice");
		map.put("物业费", "getStotalManage");
		map.put("管理费", "getStotalProperty");
		map.put("公共能耗费", "getStotalEnergy");
		map.put("居间服务费", "getStotalInter");
		map.put("保证金", "getStotalBond");
		map.put("停车费", "getStotalStop");
		map.put("租场费", "getStotalOther1");
		map.put("其他", "getStotalOther");
		return map;
	}

	private Map<String, Object> alphabetBear(List<String> itemList) {
		Map<String, Object> alphabetBear = new HashMap<String, Object>();
		for (int i = 0; i < 3; i++) {
			for (String item : itemList) {
				alphabetBear.put(i + item, "");
			}
		}
		return alphabetBear;
	}

	public int queryTotal(Map<String, Object> map) {
		return comCollectionRecordDao.countArsr(map);
	}

	public void export(OutputStream out, Map<String, Object> map) {
		exportPrivate(out, map);
	}

	private void exportPrivate(OutputStream out, Map<String, Object> map) {
		// 声明一个工作薄
		HSSFWorkbook workbook = new HSSFWorkbook();
		// 生成一个表格
		HSSFSheet sheet = workbook.createSheet();
		// 生成数字样式
		HSSFCellStyle numberStyle = workbook.createCellStyle();
		numberStyle.setAlignment(HSSFCellStyle.ALIGN_RIGHT);
		// 生成文字样式
		HSSFCellStyle style = workbook.createCellStyle();
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		// 生成一个字体
		HSSFFont font = workbook.createFont();
		font.setFontHeightInPoints((short) 12);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		// 把字体应用到当前的样式
		style.setFont(font);
		// 生成excel内容
		List<String> itemList = null;
		if (null != map.get("items") && StringUtils.isNotBlank(map.get("items").toString().trim())
				&& !StringUtils.equals("点击选择...", map.get("items").toString().trim())) {
			itemList = new ArrayList<String>(Arrays.asList(map.get("items").toString().replace(" ", "").split(",")));
		} else {
			itemList = itemList();
		}
		// 合并单元格
		List<ComGroupHeaders> ComGroupHeadersList = initializationGroupHeaders(itemList);
		List<String> colNames = initializationColNames(itemList);
		HSSFRow rowOne = sheet.createRow(0);
		HSSFCell cell = null;
		for (int i = 0; i < 3; i++) {
			sheet.addMergedRegion(new CellRangeAddress(0, 1, i, i));
			cell = rowOne.createCell(i);
			cell.setCellStyle(style);
			cell.setCellValue(colNames.get(i));
		}
		for (int i = 0; i < ComGroupHeadersList.size(); i++) {
			sheet.addMergedRegion(new CellRangeAddress(0, 0, 3 + ComGroupHeadersList.get(i).getNumberOfColumns() * i,
					2 + ComGroupHeadersList.get(i).getNumberOfColumns() * (i + 1)));
			cell = rowOne.createCell(3 + ComGroupHeadersList.get(i).getNumberOfColumns() * i);
			cell.setCellStyle(style);
			cell.setCellValue(ComGroupHeadersList.get(i).getTitleText());
		}
		HSSFRow rowTwo = sheet.createRow(1);
		for (int i = 0; i < colNames.size(); i++) {
			if (i < 3) {
				continue;
			}
			cell = rowTwo.createCell(i);
			cell.setCellStyle(style);
			cell.setCellValue(colNames.get(i));
		}
		List<ComColModel> colModel = initializationColModel(itemList);
		List<Map<String, Object>> chinaJoy = queryList(map);
		for (int i = 0; i < chinaJoy.size(); i++) {
			Map<String, Object> alphabetBear = chinaJoy.get(i);
			HSSFRow row = sheet.createRow(i + 2);
			for (int j = 0; j < colModel.size(); j++) {
				cell = row.createCell(j);
				if (j < 3) {
					cell.setCellStyle(style);
				} else {
					cell.setCellStyle(numberStyle);
				}
				cell.setCellValue(alphabetBear.get(colModel.get(j).getName()).toString());
			}
		}
		try {
			workbook.write(out);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}
